﻿/*
 * ============ [ 废土 ] ============
 *
 * [ 维护者 ]  argoran@gmail.com
 * [  状态  ]  原型
 *
 * ============ [ 注释 ] ============
 *
 * 用于控制和管理玩家计时器事件的类
 *
 * ==================================
 */

using System;
using System.Collections.Generic;

using Up2Link.SegString;

namespace LastLand.Data.Connection
{
    public class CTimerManager
    {
        private class CTimer
        {
            public CMessageSS event_ = null;
            public DateTime startTime_ = DateTime.UtcNow;
            public TimeSpan waitTime_ = TimeSpan.Zero;
            public Boolean activated_ = false;
            public Boolean running_ = false;
            public Boolean loop_ = false;
        }

        private List<CTimer> timerPool_ = null;
        private Stack<Int32> availableTimer_ = null;
        private Queue<CMessageSS> readyEvent_ = null;

        public static Int64 MillisecondsToTicks(Int32 _millisecond)
        {
            return _millisecond * TimeSpan.TicksPerMillisecond;
        }

        public CTimerManager()
        {
            timerPool_ = new List<CTimer>();
            availableTimer_ = new Stack<Int32>();
            readyEvent_ = new Queue<CMessageSS>();
        }

        public void UpdateTimerPool()
        {
            if (timerPool_.Count - availableTimer_.Count > 0)
            {
                Int32 timerCount = timerPool_.Count;
                for (Int32 i = 0; i < timerCount; i++)
                {
                    if (timerPool_[i].activated_
                        && timerPool_[i].running_
                        && DateTime.UtcNow.Subtract(timerPool_[i].startTime_).CompareTo(timerPool_[i].waitTime_) >= 0)
                    {
                        timerPool_[i].activated_ = false;
                        availableTimer_.Push(i);                        
                        readyEvent_.Enqueue(timerPool_[i].event_);

                        if (timerPool_[i].loop_)
                        {
                            ActivateTimer(timerPool_[i].event_, timerPool_[i].waitTime_, timerPool_[i].loop_);
                        }
                    }
                }
            }
        }

        public CMessageSS GetReadyTimerEvent()
        {
            if (readyEvent_.Count > 0)
            {
                return readyEvent_.Dequeue();
            }
            return null;
        }

        public Int32 ActivateTimer(CMessageSS _event, TimeSpan _waitTime, Boolean _loop)
        {
            if (_event != null && _waitTime != null)
            {
                if (availableTimer_.Count > 0)
                {
                    Int32 timerIndex = availableTimer_.Pop();
                    timerPool_[timerIndex].event_ = _event;
                    timerPool_[timerIndex].activated_ = true;
                    timerPool_[timerIndex].running_ = true;
                    timerPool_[timerIndex].loop_ = _loop;
                    timerPool_[timerIndex].waitTime_ = _waitTime;
                    timerPool_[timerIndex].startTime_ = DateTime.UtcNow;
                    return timerIndex;
                }
                else
                {
                    CTimer timer = new CTimer();
                    timer.event_ = _event;
                    timer.activated_ = true;
                    timer.running_ = true;
                    timer.loop_ = _loop;
                    timer.waitTime_ = _waitTime;
                    timer.startTime_ = DateTime.UtcNow;
                    timerPool_.Add(timer);
                    return timerPool_.Count - 1;
                }
            }
            return -1;
        }

        public void DesactivateTimer(Int32 _timerIndex)
        {
            if (_timerIndex >= 0 && _timerIndex < timerPool_.Count && timerPool_[_timerIndex].activated_)
            {
                timerPool_[_timerIndex].activated_ = false;
                timerPool_[_timerIndex].running_ = false;
                availableTimer_.Push(_timerIndex);
            }
        }

        public void PauseTimer(Int32 _timerIndex)
        {
            if (_timerIndex >= 0 && _timerIndex < timerPool_.Count && timerPool_[_timerIndex].activated_)
            {
                timerPool_[_timerIndex].running_ = false;
            }
        }

        public void ResumeTimer(Int32 _timerIndex)
        {
            if (_timerIndex >= 0 && _timerIndex < timerPool_.Count && timerPool_[_timerIndex].activated_)
            {
                timerPool_[_timerIndex].running_ = true;
            }
        }
    }
}
